#include <stdio.h>

/* 使用宏函数的时候，每一个参数一定都要加括号！！！
 * 因为宏函数只做文本替换，没有运算，
 * 在做文本替换的时候可能会改变该部分代码的运算的顺序，导致错误的结果。
 *
 * 宏函数必须在一行写完，如果为了好看想多行写，需要加续行符 ‘\’
 *
 * 宏函数不能出现分号
 */
#define MAX(a, b)   (a) > (b) ? (a) : (b)
#define SQUARE(x)   (x) * (x)
//#define SQUARE(x)   x * x     // 这是错误的


/* 不建议直接使用{}进行包裹宏函数的多个语句，很可能导致错误，如下面的代码：
 * #define SWAP(x,y) {int tmp; tmp = x; x = y; y = tmp;}
 *
 * if(x > y)
 *    SWAP(x, y);
 * else        //error, parse error before else
 *    otheraction();
 *    
 * 在把宏引入代码中，会多出一个分号，从而会报错。
 * 应该使用do { } while(0) 把它包裹起来，成为一个独立的语法单元，从而不会与上下文发生混淆。
 *
 */
#define SWAP(a, b) { \
    typeof(a) (t); \
    (t) = (a); \
    (a) = (b); \
    (b) = (t); \
}

// typeof(a) 关键字表示获取a的数据类型
#define SWAP2(a, b) \
do { \
    typeof(a) (t); \
    (t) = (a); \
    (a) = (b); \
    (b) = (t); \
} while(0) // 注意此处不加分号

int main(void)
{
    int a, b;
    scanf("%d%d", &a, &b);

    printf("max:%d\n", MAX(a, b));
    printf("square:%d\n", SQUARE(a));
    printf("square:%d\n", SQUARE(a + 1)); // 不加括号会变成 a + 1 * a + 1

    SWAP(a, b);
    printf("a = %d, b = %d\n", a, b);

    SWAP2(a, b);
    printf("a = %d, b = %d\n", a, b);
    return 0;
}

